package org.zxyj.manage.service.impl;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.zxyj.core.constants.Dict;
import org.zxyj.core.constants.SysParamsDict;
import org.zxyj.core.utils.Common;
import org.zxyj.core.utils.MessageUtil;
import org.zxyj.core.utils.RequestUtils;
import org.zxyj.core.utils.UUIDUtils;
import org.zxyj.manage.controller.PaperCheckThread;
import org.zxyj.manage.entity.CoursePaperDetail;
import org.zxyj.manage.entity.Examinee;
import org.zxyj.manage.service.ICheckService;
import org.zxyj.manage.service.ICoursePaperService;
import org.zxyj.manage.service.ICourseTemplateService;
import org.zxyj.manage.service.ICropService;
import org.zxyj.manage.service.IPointRecognitionService;
import org.zxyj.manage.thread.WorkThreadFactory;

@Service
public class CheckServiceImpl implements ICheckService{
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	//读取配置文件
    //private static PropertiesUtil configProp = PropertiesUtil.newInstance(Thread.currentThread().getContextClassLoader().getResource("").getPath() + "config/config.properties");
    //初始化线程池
    private ExecutorService service = Executors.newFixedThreadPool(Integer.valueOf(MessageUtil.getExtConfig("system.max_thread_num")),new WorkThreadFactory());
    
    @Autowired
    private ICropService cropService;
    @Autowired
    private IPointRecognitionService pointRecognitionService;
    @Autowired
	private ICourseTemplateService courseTemplateService;
    @Autowired
    private ICoursePaperService coursePaperService;
    

    /**
     * 获取模板起始点与答卷起始点偏差值-第一遍
     * @param image 图片流
     * @return 
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public Map<String,Integer> getTempStartPointFirst(BufferedImage image) throws IOException{
        //识别答卷定位点坐标
        Map<String,Object> map = pointRecognitionService.getAreaResult(image,2);
        Map<String,Integer> param = new HashMap<String,Integer>();
        param.put("start_pos_x", Integer.parseInt(map.get("start_x")+""));//图像内容实际起始点X
        param.put("start_pos_y", Integer.parseInt(map.get("start_y")+""));//图像内容实际起始点Y
        return param;
    }
    
    /**
     * 对答卷进行偏正校正-校验用
     * @param kmdjUrl 科目答卷路径
     * @param start_pos_x X轴偏移量
     * @param start_pos_y Y轴偏移量
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public Map<String,Object> getBufferedResultForCheck(String kmdjUrl,int start_pos_x,int start_pos_y) throws IOException{
    public Map<String,Object> getBufferedResultForCheck(Map<String,Object> params) throws IOException{
        String sourceUrl = String.valueOf(params.get("sourceUrl"));
        Integer start_pos_x = Integer.valueOf(String.valueOf(params.get("start_pos_x")));
        Integer start_pos_y = Integer.valueOf(String.valueOf(params.get("start_pos_y")));
    	//kmdjCheckController.cropPosRightTop(kmdjUrl,tempPicUrl,tzdName,null);
        BufferedImage biRight = cropService.cropPosRightTopBuffered(sourceUrl,null);
        
        //int len = kmdjUrl.lastIndexOf(".");
        //String destUrl = kmdjUrl.substring(0, len)+fileType;
        double rotate =0.0;
        params.put("rotate", rotate);
        //imageMagickTool = new ImageMagickTool();
        BufferedImage image1 = cropService.imageRotateToBuff(params);
        //BufferedImage image1 = kmdjCheckController.readImageBuffered(destUrl);//读取文件流
        int imgWidth = image1.getWidth();
        
        int X1 = start_pos_x;//左侧起始点X
        int Y1 = start_pos_y;//左侧起始点Y
        //计算右侧特征点坐标
        //tempPicUrl += tzdName;
        //BufferedImage image = kmdjCheckController.readImageBuffered(tempPicUrl);//读取文件流
        Map<String,Object> resultMap = pointRecognitionService.getAreaResult(biRight,3);
        int X2 = Integer.parseInt(resultMap.get("start_x")+"");
        int Y2 = Integer.parseInt(resultMap.get("start_y")+"");
        int pcY = Y2 - Y1;
        if (Math.abs(pcY) >= 1) {
            // 需要处理矫正
            double num = Double.valueOf(Math.abs(pcY)) /(imgWidth-X2-X1);
            if(pcY<0){
                rotate = Math.atan(num)*180/Math.PI;
            }else if(pcY>0){
                rotate = -Math.atan(num)*180/Math.PI;
            }
            BigDecimal bg = new BigDecimal(rotate);
            rotate = bg.setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue();
        }
        image1=null;
        biRight=null;
        //旋转方法：
        params.put("rotate", rotate);
        BufferedImage bi = cropService.imageRotateToBuff(params);//执行偏正校正
        
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("rotate", rotate);
        map.put("image", bi);
        return map;
    }
    
    /**
     * 对答卷进行偏正校正-正面模板设置用
     * @param kmdjUrl 科目答卷路径
     * @param tempPicUrl 临时文件路径
     * @param tzdName 文件名称
     * @param start_pos_x X轴偏移量
     * @param start_pos_y Y轴偏移量
     * @param fileType 文件类型
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public String getBufferedResultForTempZm(String kmdjUrl,String tempPicUrl,String tzdName,int start_pos_x,int start_pos_y,String fileType) throws IOException{
    public String getBufferedResultForTempZm(Map<String,Object> params) throws IOException{
    	String sourceUrl = params.get("sourceUrl")+"";
    	String tempPicUrl = params.get("destUrl")+"";
    	String imgName = params.get("imgName")+"";
    	cropService.cropPosRightTop(sourceUrl,tempPicUrl,imgName);
        int len = sourceUrl.lastIndexOf(".");
        String destUrl = sourceUrl.substring(0, len)+params.get("fileType");
        double rotate =0.0;
        params.put("destUrl", destUrl);
        params.put("rotate", rotate);
        cropService.imageRotateToFile(params);
        BufferedImage image1 = cropService.readImageBuffered(destUrl);//读取文件流
        int imgWidth = image1.getWidth();
        
        int X1 = Integer.valueOf(params.get("start_pos_x")+"");//左侧起始点X
        int Y1 = Integer.valueOf(params.get("start_pos_y")+"");//左侧起始点Y
        //计算右侧特征点坐标
        tempPicUrl += imgName;
        BufferedImage image = cropService.readImageBuffered(tempPicUrl);//读取右侧特征点文件流
        Map<String,Object> resultMap = pointRecognitionService.getAreaResult(image,3);
        int X2 = Integer.parseInt(resultMap.get("start_x")+"");
        int Y2 = Integer.parseInt(resultMap.get("start_y")+"");
        int pcY = Y2 - Y1;
        if (Math.abs(pcY) >= 1) {
            // 需要处理矫正
            double num = Double.valueOf(Math.abs(pcY)) /(imgWidth-X2-X1);
            if(pcY<0){
                rotate = Math.atan(num)*180/Math.PI;
            }else if(pcY>0){
                rotate = -Math.atan(num)*180/Math.PI;
            }
        }
        image1=null;
        //旋转方法：
        params.put("rotate", rotate);
        cropService.imageRotateToFile(params);//执行偏正校正
        return destUrl;
    }
    
    /**
     * 对答卷进行偏正校正-反面模板设置用
     * @param kmdjUrl 科目答卷路径
     * @param tempPicUrl 临时文件路径
     * @param tzdName 文件名称
     * @param start_pos_x X轴偏移量
     * @param start_pos_y Y轴偏移量
     * @param fileType 文件类型
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public String getBufferedResultForTempFm(String kmdjUrl,String tempPicUrl,String tzdName,int start_pos_x,int start_pos_y,String fileType) throws IOException{
    public String getBufferedResultForTempFm(Map<String,Object> params) throws IOException{
    	String sourceUrl = params.get("sourceUrl")+"";
        int len = sourceUrl.lastIndexOf(".");
        String destUrl = sourceUrl.substring(0, len)+params.get("fileType");
        params.put("destUrl", destUrl);
        params.put("rotate", 0.0);
        //旋转方法：
        cropService.imageRotateToFile(params);//执行偏正校正
        return destUrl;
    }
    
    /**
     * 判断是否缺考答卷
     * @param record 答卷记录
     * @param image 图片流
     * @param p_x X轴偏移量
     * @param p_y Y轴偏移量
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public boolean judgeQk(Map<String,Object> record,BufferedImage image,int p_x,int p_y) throws IOException{
    public boolean judgeQk(Map<String,Object> params) throws IOException{
    	
        //获取缺考区域图片流
        //Map<String,String> qkAreaMap = getQkBufferedImage(record,image,p_x,p_y);
        Map<String,Object> qkAreaMap = getQkBufferedImage1(params);
        //String picurl_ = qkAreaMap.get("tempPicUrl");
        //BufferedImage image_qk = kmdjCheckController.readImageBuffered(picurl_);//读取缺考文件流
        BufferedImage image_qk = (BufferedImage)qkAreaMap.get("qkImage");
        //识别缺考区域是否填涂
        int qk_area_width = Integer.parseInt(qkAreaMap.get("area_width")+"");
        int qk_area_height = Integer.parseInt(qkAreaMap.get("area_height")+"");
        int blank_x = Integer.parseInt(qkAreaMap.get("blank_x")+"");
        int blank_y = Integer.parseInt(qkAreaMap.get("blank_y")+"");
        return pointRecognitionService.recognitionQk(image_qk,qk_area_width,qk_area_height,1,1,blank_x,blank_y);
    }
    
    /**
     * 裁剪缺考区域
     * @param record 答卷记录
     * @param image 图片流
     * @param p_x X轴偏移量
     * @param p_y Y轴偏移量
     * @return
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public Map<String,String> getQkBufferedImage(Map<String,Object> record,BufferedImage image,int p_x,int p_y){
    public Map<String,String> getQkBufferedImage(Map<String,Object> params){
    	Map<String,Object> record = (Map<String, Object>) params.get("record");
    	BufferedImage image = (BufferedImage) params.get("image");
    	Integer p_x = Integer.valueOf(params.get("p_x")+"");
    	Integer p_y = Integer.valueOf(params.get("p_y")+"");
    	
    	String fileTempDir = MessageUtil.getExtConfig("fj.temp.pic.url");
        //获取考生编号区域坐标点
        Map<String,Object> map = new HashMap<String,Object>();
        Map<String,String> result = new HashMap<String,String>();
        int x1 = Integer.parseInt(record.get("x1")+"");
        int x2 = Integer.parseInt(record.get("x2")+"");
        int y1 = Integer.parseInt(record.get("y1")+"");
        int y2 = Integer.parseInt(record.get("y2")+"");
        int blank_x = Integer.parseInt(record.get("start_x")+"")-1;//标准填涂区起始点X
        int blank_y = Integer.parseInt(record.get("start_y")+"")-1;//标准填涂区起始点Y
        int area_width = Integer.parseInt(record.get("area_width")+"");//标准填涂区宽度
        int area_height = Integer.parseInt(record.get("area_height")+"");//标准填涂区高度
        //根据偏差值计算出每个考生答卷实际坐标点
        x1 = x1 + p_x;
        x2 = x2 + p_x;
        y1 = y1 + p_y;
        y2 = y2 + p_y;
        int width = x2 -x1;
        int height = y2 -y1;
        map.put("width", width);
        map.put("height", height);
        map.put("start_x", x1);
        map.put("start_y", y1);
            
        //裁剪考生编号区域
        String imgName = UUIDUtils.UUID() + "."+Dict.IMAGE_FORMAT.PNG;
        String destUrl = fileTempDir;//临时图片存放路径
        map.put("imgName", imgName);
        map.put("destUrl", destUrl);
        map.put("image", image);
        cropService.cropPos1(map);
        
        result.put("area_width", area_width+"");
        result.put("area_height", area_height+"");
        result.put("blank_x", blank_x+"");
        result.put("blank_y", blank_y+"");
        result.put("tempPicUrl", destUrl+imgName);
        return result;
    }
    
    /**
     * 裁剪缺考区域
     * @param record 答卷记录
     * @param image 图片流
     * @param p_x X轴偏移量
     * @param p_y Y轴偏移量
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public Map<String,Object> getQkBufferedImage1(Map<String,Object> record,BufferedImage image,int p_x,int p_y) throws IOException{
    public Map<String,Object> getQkBufferedImage1(Map<String,Object> params) throws IOException{
    	Map<String,Object> record = (Map<String, Object>) params.get("record");
    	BufferedImage image = (BufferedImage) params.get("image");
    	Integer p_x = Integer.valueOf(params.get("p_x")+"");
    	Integer p_y = Integer.valueOf(params.get("p_y")+"");
    	
        //获取考生编号区域坐标点
        Map<String,Integer> map = new HashMap<String,Integer>();
        Map<String,Object> result = new HashMap<String,Object>();
        int x1 = Integer.parseInt(record.get("x1")+"");
        int x2 = Integer.parseInt(record.get("x2")+"");
        int y1 = Integer.parseInt(record.get("y1")+"");
        int y2 = Integer.parseInt(record.get("y2")+"");
        int blank_x = Integer.parseInt(record.get("startX")+"")-1;//标准填涂区起始点X
        int blank_y = Integer.parseInt(record.get("startY")+"")-1;//标准填涂区起始点Y
        int area_width = Integer.parseInt(record.get("areaWidth")+"");//标准填涂区宽度
        int area_height = Integer.parseInt(record.get("areaHeight")+"");//标准填涂区高度
        //根据偏差值计算出每个考生答卷实际坐标点
        x1 = x1 + p_x;
        x2 = x2 + p_x;
        y1 = y1 + p_y;
        y2 = y2 + p_y;
        int width = x2 -x1;
        int height = y2 -y1;
        map.put("width", width);
        map.put("height", height);
        map.put("start_x", x1);
        map.put("start_y", y1);
        
        //裁剪考生编号区域
        /*String imgName = UUID.randomUUID().toString()+ ".png";
        String tempPicUrl = CommonConfig.FJ_URL + "temp_pic/";//临时图片存放路径
        cropService.cropPos1(image,tempPicUrl,imgName,params);*/
        BufferedImage qkImage = cropService.cropPosBuffered(image,map);//裁剪
        
        result.put("area_width", area_width+"");
        result.put("area_height", area_height+"");
        result.put("blank_x", blank_x+"");
        result.put("blank_y", blank_y+"");
        result.put("qkImage", qkImage);
        //param.put("tempPicUrl", tempPicUrl+imgName);
        return result;
    }
    
    /**
     * 裁剪校验反面答卷
     * @param r 记录
     * @param posMap2 反面特征点信息
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    public Map<String,Integer> cropCheckFmdj(CoursePaperDetail record,Map<String,Object> posMap2) throws IOException{
    	String fileDir = MessageUtil.getExtConfig("fj.course.paper.url");
    	String mbid2 = (String) record.getCourseTemplateId();//反面模板id
        String kmdjUrl2 = fileDir + record.getFilePath();//答卷存储路径
        //String imgName2 = UUID.randomUUID().toString()+ ".png";
        //String tempPicUrl2 = CommonConfig.FJ_URL + "temp_pic/";//临时图片存放路径
        //kmdjCheckController.cropPos(kmdjUrl2,tempPicUrl2,imgName2,null);//裁剪特征点区域
        //BufferedImage image_dj2 = kmdjCheckController.readImageBuffered(tempPicUrl2+imgName2);//读取文件流
        
        BufferedImage image_dj2 = cropService.cropPosBuffered(kmdjUrl2,null);//裁剪特征点区域
        //获取模板起始坐标点与答卷起始点偏差值
        Map<String,Object> args = new HashMap<String,Object>();
        args.put("image", image_dj2);
        args.put("record", posMap2.get(mbid2));
        Map<String,Integer> posDiffMap2 = getTempStartPoint(args);
        //Map<String,Integer> posDiffMap2 = getTempStartPoint(image_dj2,(Map<String, Object>) posMap2.get(mbid2));
        int p_x2 = posDiffMap2.get("p_x");
        int p_y2 = posDiffMap2.get("p_y");
        image_dj2 = null;

        Map<String,Integer> diffMap2 = new HashMap<String,Integer>();
        diffMap2.put("p_x", p_x2);
        diffMap2.put("p_y", p_y2);
        return diffMap2;
    }
    
    /**
     * 获取模板起始点与答卷起始点偏差值
     * @param image 图片流
     * @param r 记录
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public Map<String,Integer> getTempStartPoint(BufferedImage image,Map<String,Object> r) throws IOException{
    public Map<String,Integer> getTempStartPoint(Map<String,Object> params) throws IOException{
    	Map<String,Object> record = (Map<String, Object>) params.get("record");
    	BufferedImage image = (BufferedImage) params.get("image");
    	
        int start_x = Integer.parseInt(record.get("x1")+"") + Integer.parseInt(record.get("startX")+"");//模板实际起始坐标点X
        int start_y = Integer.parseInt(record.get("y1")+"") + Integer.parseInt(record.get("startY")+"");//模板实际起始坐标点Y
        
        //识别答卷定位点坐标
        Map<String,Object> map = pointRecognitionService.getAreaResult(image,2);
        int start_pos_x = Integer.parseInt(map.get("start_x")+"");//图像内容实际起始点X
        int start_pos_y = Integer.parseInt(map.get("start_y")+"");//图像内容实际起始点Y
        image = null;
       // System.out.println("start_pos_x="+start_pos_x +",start_pos_y="+start_pos_y);
        
        //将得到的特征点起始点坐标与模板中起始点坐标比对，计算X,Y轴偏差值
        int p_x = start_pos_x - start_x;
        int p_y = start_pos_y - start_y;
        
        Map<String,Integer> param = new HashMap<String,Integer>();
        param.put("p_x", p_x);
        param.put("p_y", p_y);
        param.put("start_pos_x", start_pos_x);
        param.put("start_pos_y", start_pos_y);
        return param;
    }
    
    /**
     * 裁剪考生编号区域
     * @param r_ksbh 考号
     * @param image 图片流
     * @param p_x X轴偏移量
     * @param p_y Y轴偏移量
     * @return
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
    //public Map<String,Object> getKsbhBufferedImage(Map<String,Object> r_ksbh,BufferedImage image,int p_x,int p_y) throws IOException{
    public Map<String,Object> getKsbhBufferedImage(Map<String,Object> params) throws IOException{
    	Map<String,Object> ksMap = (Map<String, Object>) params.get("ksMap");
    	BufferedImage image = (BufferedImage) params.get("image");
    	Integer p_x = Integer.valueOf(params.get("p_x")+"");
    	Integer p_y = Integer.valueOf(params.get("p_y")+"");
    	
    	//获取考生编号区域坐标点
        Map<String,Integer> map = new HashMap<String,Integer>();
        Map<String,Object> result = new HashMap<String,Object>();
        int x1 = Integer.parseInt(ksMap.get("x1")+"");
        int x2 = Integer.parseInt(ksMap.get("x2")+"");
        int y1 = Integer.parseInt(ksMap.get("y1")+"");
        int y2 = Integer.parseInt(ksMap.get("y2")+"");
        int area_width = Integer.valueOf(ksMap.get("areaWidth")+"");//考号区宽度
        int area_height = Integer.valueOf(ksMap.get("areaHeight")+"");//考号区高度
        int kh_start_x = Integer.valueOf(ksMap.get("startX")+"");//考号区实际起始点X
        int kh_start_y = Integer.valueOf(ksMap.get("startY")+"");//考号区实际起始点Y
        int row_count = Integer.valueOf(ksMap.get("rowCount")+"");//考号行数
        int col_count = Integer.valueOf(ksMap.get("colCount")+"");//考号列数
        //根据偏差值计算出每个考生答卷实际坐标点
        x1 = x1 + p_x;
        x2 = x2 + p_x;
        y1 = y1 + p_y;
        y2 = y2 + p_y;
        int width = x2 -x1;
        int height = y2 -y1;
        map.put("width", width);
        map.put("height", height);
        map.put("start_x", x1);
        map.put("start_y", y1);
            
        //裁剪考生编号区域
        //String imgKsbh = UUID.randomUUID().toString()+ ".png";
        //String tempPicUrl = CommonConfig.FJ_URL + "temp_pic/";//临时图片存放路径
        //kmdjCheckController.cropPos1(image,tempPicUrl,imgKsbh,params);
        BufferedImage khImage = cropService.cropPosBuffered(image,map);//裁剪
        /*params.put("destUrl", configProp.getValue("fj.temp.pic.url"));
        params.putAll(map);
        params.put("imgName", UUIDUtils.UUID()+".png");
        cropService.cropPos1(params);*/
        image = null;
        //param.put("area_width", area_width+"");
        //param.put("area_height", area_height+"");
        result.put("row_count", row_count+"");
        result.put("col_count", col_count+"");
        //result.put("tempPicUrl", tempPicUrl+imgKsbh);
        result.put("kh_start_x", kh_start_x+"");
        result.put("kh_start_y", kh_start_y+"");
        result.put("area_width", area_width+"");
        result.put("area_height", area_height+"");
        result.put("khImage", khImage);
        return result;
    }

    /**
     * 查询答卷信息列表并进行校验
     * @param attrachmentId1 正面模板id
     * @param attrachmentId2 反面模板id
     * @param batchId 考试批次id
     * @param gradeNo 年级号
     * @param courseNo 课程号
     * @return 返回值代码：000001-模板没查到,000002-考生未查到,000003-正面答卷未查到,000004-通过
     * @throws IOException
     * @see   [类、类#方法、类#成员]
     * @since [产品/模块版本]
     */
	@SuppressWarnings("unchecked")
	public void checkTemplate(Map<String, Object> criteria) {
		ConcurrentHashMap<String,Object> map = new ConcurrentHashMap<String,Object>();
        //查询科目模板所有切割区域
        String courseTemplateId1 = (String) criteria.get("courseTemplateId1");
        String courseTemplateId2 = (String) criteria.get("courseTemplateId2");
        List<String> tempIds = (List<String>) criteria.get("tempIds");
        if(!CollectionUtils.isEmpty(tempIds)){
        	List<Map<String,Object>> list = this.courseTemplateService.queryCourseTemplateArea(criteria);
            Map<String,Object> posMap1 = new HashMap<String,Object>();//正面特征点
            Map<String,Object> posMap2 = new HashMap<String,Object>();//反面特征点
            Map<String,Object> ksbhMap = new HashMap<String,Object>();//考号
            Map<String,Object> qkMap = new HashMap<String,Object>();//缺考
            Map<String,Object> singleMap = new HashMap<String,Object>();//单选题
            Map<String,Object> moreMap = new HashMap<String,Object>();//多选题
            Map<String,Object> zgMap1 = new HashMap<String,Object>();//正面主观题
            Map<String,Object> zgMap2 = new HashMap<String,Object>();//反面主观题
            Map<String,Map<String,Object>> cjcsMap = new HashMap<String,Map<String,Object>>();//裁剪参数组合map
            Map<String,Object> ksxxMap = new HashMap<String,Object>();//基本参数
            ksxxMap.put("batchId", criteria.get("batchId"));
            ksxxMap.put("gradeNo", criteria.get("gradeNo"));
            ksxxMap.put("courseNo", criteria.get("courseNo"));
            ksxxMap.put("userId", Common.findUserSessionId());
            if(!CollectionUtils.isEmpty(list)){
            	//查询模板对应的待处理的考生答卷
            	Map<String,Object> params = new HashMap<String,Object>();
            	params.put("isPass", 0);
                List<CoursePaperDetail> kmdjList1 = new ArrayList<CoursePaperDetail>();
                List<CoursePaperDetail> kmdjList2 = new ArrayList<CoursePaperDetail>();
                Map<String,CoursePaperDetail> kmdjListMap = new HashMap<String,CoursePaperDetail>();
                if(!StringUtils.isEmpty(courseTemplateId1)){
                	params.put("zfmType", 1);
                	params.put("tempId", courseTemplateId1);
                	kmdjList1 = this.coursePaperService.findCoursePaperDetailList(params);//查询正面
                	if(!StringUtils.isEmpty(courseTemplateId2)){
                    	params.put("zfmType", 2);
                    	params.put("tempId", courseTemplateId2);
                    	kmdjList2 = this.coursePaperService.findCoursePaperDetailList(params);//查询正面
                    	
                        //遍历反面答卷
                        if(!CollectionUtils.isEmpty(kmdjList2)){
                            for(CoursePaperDetail r : kmdjList2){
                                kmdjListMap.put(r.getFileName().split("_")[0], r);
                            }
                        }
                    }
                }
                
                //查询考生数据
                Map<String,Examinee> ksAllMap = new HashMap<String,Examinee>();//所有考生map
                List<Examinee> ksList = this.coursePaperService.queryExamineeList(ksxxMap);
                if(!CollectionUtils.isEmpty(ksList)){
                    for(Examinee r : ksList){
                        String kh = r.getExaNo();//考号
                        ksAllMap.put(kh, r);
                    }
                }else{
                	map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                    map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NOSTUDENT.getValue());
                    RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                    return;
                }
                
            	int areaWidth = 0;
                int areaHeight = 0;
                for(Map<String,Object> record : list){
                    //获取模板特征点定位区截图信息
                    String lx = (String) record.get("lx");//区域类型
                    String id = (String) record.get("id");
                    String mbid = (String) record.get("owner");
                    int zfm = Integer.valueOf(record.get("zfmType")+"");//正反面
                    if(zfm==1){
                        if(lx.equals("0")){//特征点区域
                            posMap1.put(mbid, record);//正面获取特征点文件存储信息
                        }else if(lx.equals("1")){//考生编号区域
                            ksbhMap.put(mbid, record);
                        }else if(lx.equals("2")){//考号填涂区
                            areaWidth = record.get("areaWidth")==null?0:Integer.valueOf(record.get("areaWidth")+"");
                            areaHeight = record.get("areaHeight")==null?0:Integer.valueOf(record.get("areaHeight")+"");
                        }else if(lx.equals("9")){//缺考区域
                            qkMap.put(mbid, record);
                        }else if(lx.equals("3")){//客观题单选区域
                            singleMap.put(id, record);
                        }else if(lx.equals("4")){//客观题多选区域
                            moreMap.put(id, record);
                        }else if(lx.equals("5")){//主观题区域
                            zgMap1.put(id, record);
                        }
                    }else{
                        if(lx.equals("0")){//特征点区域
                            posMap2.put(mbid, record);//反面获取特征点文件存储信息
                        }else if(lx.equals("5")){//主观题区域
                            zgMap2.put(id, record);
                        } 
                    }
                }
                
                if(posMap1.isEmpty()){
                	map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                    map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NO_ZMTZD.getValue());//未设置正面特征点
                    RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                    return;
                }
                if(posMap2.isEmpty()){
                	map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                    map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NO_FMTZD.getValue());//未设置反面特征点
                    RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                    return;
                }
                if(ksbhMap.isEmpty()){
                	map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                    map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NO_KSBH.getValue());//未设置考生编号
                    RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                    return;
                }
                if(areaWidth ==0 || areaHeight ==0){
                	map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                    map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NO_KSBHCJ.getValue());//未设置考生编号采集点或设置不正确
                    RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                    return;
                }
                if(qkMap.isEmpty()){
                	map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                	map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NO_QK.getValue());//未设置缺考
                	RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                	return;
                }
                cjcsMap.put("singleMap", singleMap);
                cjcsMap.put("moreMap", moreMap);
                cjcsMap.put("zgMap1", zgMap1);
                cjcsMap.put("zgMap2", zgMap2);
                
                //遍历正面答卷
                if(!CollectionUtils.isEmpty(kmdjList1)){
                    Map<String,Map<String,CoursePaperDetail>> sbsbMap1 = new HashMap<String,Map<String,CoursePaperDetail>>();
                    Map<String,Map<String,String>> kmdjQkMap1 = new HashMap<String,Map<String,String>>();
                    Map<String,Map<String,String>> sbcgMap1 = new HashMap<String,Map<String,String>>();//识别成功map
                    Map<String,Map<String,String>> bdsbMap1 = new HashMap<String,Map<String,String>>();//考生比对失败map
                    Map<String,Integer> qkksMap1 = new HashMap<String, Integer>();//缺考考生数
                    
                    map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                    map.put("djzs", kmdjList1.size()+"");
                    RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                    RequestUtils.setSessionAttr("sbsbMap",sbsbMap1);
                    RequestUtils.setSessionAttr("kmdjQkMap",kmdjQkMap1);
                    RequestUtils.setSessionAttr("sbcgMap",sbcgMap1);
                    RequestUtils.setSessionAttr("qkksMap",qkksMap1);
                    RequestUtils.setSessionAttr("bdsbMap",bdsbMap1);
                    
                    //开启多线程处理任务
                    int recordSize = kmdjList1.size();
                    int threadNum =0;
                    List<CoursePaperDetail> rList = new ArrayList<CoursePaperDetail>();
                    for(int i=0;i<recordSize;i++){
                        rList = new ArrayList<CoursePaperDetail>();
                        rList.add(kmdjList1.get(i));
                        threadNum++;
                        logger.info("__________________________记录数量线程启动前"+i);
                        Map<String,Object> map_ = new HashMap<String,Object>();
                        map_.put("threadNum", threadNum);
                        map_.put("rList", rList);
                        map_.put("kmdjListMap", kmdjListMap);
                        map_.put("posMap1", posMap1);
                        map_.put("posMap2", posMap2);
                        map_.put("ksbhMap", ksbhMap);
                        map_.put("qkMap", qkMap);
                        map_.put("ksAllMap", ksAllMap);
                        map_.put("areaWidth", areaWidth);
                        map_.put("areaHeight", areaHeight);
                        map_.put("cjcsMap", cjcsMap);
                        map_.put("ksxxMap", ksxxMap);
                        map_.put("baseUrl", MessageUtil.getExtConfig("fj.course.paper.url"));
                        map_.put("session", criteria.get("session"));
                        service.execute(new PaperCheckThread(map_));
                        logger.info("__________________________########记录数量线程启动后"+i);
                    }
                    
                    try {
                        // 等待线程执行完毕，不能超过2*60秒，配合shutDown
                    	service.shutdown();
                        service.awaitTermination(1, TimeUnit.SECONDS);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
                    map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NOPAPER_ZM.getValue());
                    RequestUtils.setSessionAttr("kmdjJyjgMap",map);
                    return;
                }
            }
        }else{
            map.putAll(RequestUtils.getCurrSessionAttrMap("kmdjJyjgMap"));
            map.put("resultCode", SysParamsDict.CHECK_STATUS_CODE.NOTEMP.getValue());
            RequestUtils.setSessionAttr("kmdjJyjgMap",map);
        }
	}

}
